package com.nineclock.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.sms.AliyunSmsUtils;
import com.nineclock.common.utils.PhoneNumCheckUtils;
import com.nineclock.system.service.SmsService;
import com.nineclock.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SmsServiceImpl implements SmsService {


    @Autowired
    SysUserService userService;

    @Autowired
    AliyunSmsUtils aliyunSmsUtils;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 发送验证码
     * 1. 健壮性判断
     * 2. 验证手机是否可以使用
     * 3. 生成验证码，发送验证码到手机
     * 4. 存储验证码到redis
     * @param mobile
     * @param type
     */
    @Override
    public void sendCode(String mobile, String type) {
        //健壮性判断
        if(mobile == null || type == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //验证手机是否可以使用
        if(!PhoneNumCheckUtils.isPhoneLegal(mobile)){
            throw new NcException(ResponseEnum.INVALID_PHONE_NUMBER);
        }
        //根据手机号 查询 手机号是否存在
        Integer count = userService.queryByMobile(mobile);
        //手机号用途：登录，注册，更换管理员，重置密码
        if(type.equals(SMSConstant.SMS_TYPE_REGISTER)){
            //如果是注册，手机号不能存在
            if(count > 0){
                throw new NcException(ResponseEnum.USER_MOBILE_EXISTS);
            }

        }else{
            //如果不是注册，手机号必须存在
            if(count == 0){
                throw new NcException(ResponseEnum.INVALID_PHONE_NUMBER);
            }
        }

        //生成验证码
        String code = RandomUtil.randomNumbers(6);
        log.info("验证码：" + code);

        //发送验证码到手机
//        Boolean flag = aliyunSmsUtils.sendSMS(mobile, code);
//        if(! flag){
//            throw new NcException(ResponseEnum.SEND_MESSAGE_ERROR);
//        }


        //存储验证码到redis key = type + mobile
        String key = getPrefix(type) + mobile;

        redisTemplate.boundValueOps(key).set(code, 5, TimeUnit.MINUTES);

    }

    @Override
    public Boolean verify(String mobile, String type, String checkcode) {
        if(mobile == null  || type == null || checkcode == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //获取redis中验证码
        String key = getPrefix(type) + mobile;
        String redisCode = redisTemplate.boundValueOps(key).get();

        if(redisCode != null && redisCode.equals(checkcode)){
            return true;
        }
        return false;
    }

    public String getPrefix(String type){
        switch (type){
            case SMSConstant.SMS_TYPE_LOGIN: return SMSConstant.SMS_LOGIN_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_REGISTER: return SMSConstant.SMS_REGISTER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_CHANGE_MANAGER: return SMSConstant.SMS_CHANGE_MANAGER_KEY_PREFIX;
            case SMSConstant.SMS_TYPE_RESET_PASSWORD: return SMSConstant.SMS_RESET_KEY_PREFIX;
            default: return null;
        }
    }
}
